package cn.darkhorse.ticket.store.service.impl;

import cn.darkhorse.exception.ServiceException;
import cn.darkhorse.ticket.code.RepeatCheck;
import cn.darkhorse.ticket.constants.TicketConstants;
import cn.darkhorse.ticket.store.dao.TicketOutboundDao;
import cn.darkhorse.ticket.store.dto.TicketOutboundDTO;
import cn.darkhorse.ticket.store.dto.TicketProductDetailsDTO;
import cn.darkhorse.ticket.store.dto.TicketWarehousingDTO;
import cn.darkhorse.ticket.store.mapper.TicketOutboundMapper;
import cn.darkhorse.ticket.store.pojo.TicketOutbound;
import cn.darkhorse.ticket.store.pojo.TicketOutboundSub;
import cn.darkhorse.ticket.store.pojo.TicketWarehousing;
import cn.darkhorse.ticket.store.pojo.TicketWarehousingSub;
import cn.darkhorse.ticket.store.service.TicketOutboundService;
import cn.darkhorse.ticket.store.service.TicketOutboundSubService;
import cn.darkhorse.ticket.store.service.verification.ICalculationService.IQuantityRecordService;
import cn.darkhorse.ticket.store.service.verification.impl.BasePurchaseSurplus;
import cn.darkhorse.ticket.store.service.verification.impl.BaseRetrievalSurplus;
import cn.darkhorse.ticket.store.vo.TicketOutboundVO;
import cn.darkhorse.ticket.store.vo.TicketWarehousingVO;
import cn.darkhorse.ticket.store.vo.TicketWarehousingViewVO;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 出库主表 服务实现类
 * </p>
 *
 * @author wangxinghui
 * @since 2024-01-16
 */
@Service
public class TicketOutboundServiceImpl extends ServiceImpl<TicketOutboundMapper, TicketOutbound> implements TicketOutboundService {
	
	@Resource
	private SysUserMapper userMapper;
	@Resource
	private TicketOutboundSubService outboundSubService;
	@Resource
	private RepeatCheck<TicketOutboundDTO> repeatCheck;
	
	@Resource
	private BaseRetrievalSurplus retrievalSurplus;
	
	@Resource(name = "decreaseService")
	private IQuantityRecordService decreaseService;
	@Resource
	private TicketOutboundDao outboundDao;
	
	@Override
	public List<TicketOutboundVO> list(String code, String name, String beginTime, String endTime) {
		Map<String,Object> params = new HashMap<>();
		params.put("code",code);
		params.put("name",name);
		params.put("beginTime",beginTime);
		params.put("endTime",endTime);
		List<TicketOutboundVO> list = outboundDao.list(params);
		return list;
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public String add(TicketOutboundDTO outboundDTO) {
		String s = repeatCheck.repeatCode(this, outboundDTO, TicketConstants.BUSINESS_TYPE_OUT);
		if(StringUtils.isNotBlank(s)){
			outboundDTO.setCode(s);
		}
		List<TicketOutboundSub> details = outboundDTO.getDetails();
		//校验
		List<TicketProductDetailsDTO> productDetails = getProductDetails(details);
		retrievalSurplus.setProductDetailsDTOList(productDetails);
		retrievalSurplus.check();
		//保存
		save(outboundDTO);
		details.forEach(item->{
			item.setOutboundId(outboundDTO.getId());
		});
		outboundSubService.saveBatch(details);
		//记录数量变化
		decreaseService.changeQuantity(getProductDetails(details));
		return s;
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void modify(TicketOutboundDTO outboundDTO) {
		//不需要校验编码名称
		//repeatCheck.repeat(this, outboundDTO, TicketConstants.BUSINESS_TYPE_OUT);
		//校验数量问题
		List<TicketOutboundSub> details = outboundDTO.getDetails();
		List<TicketProductDetailsDTO> productDetails = getProductDetails(getDetails(outboundDTO.getId()));
		productDetails.forEach(item->{
			item.setBusinessType("ROLLBACK");
			item.setQuantity(item.getQuantity().negate());
		});
		decreaseService.changeQuantity(productDetails);

		retrievalSurplus.setProductDetailsDTOList(getProductDetails(details));
		retrievalSurplus.check();
		//保存
		updateById(outboundDTO);
		//明细
		outboundSubService.updateBatchById(details);
		//记录数量变化
		decreaseService.changeQuantity(getProductDetails(details));
	}
	
	@Override
	public TicketOutboundVO view(Long id) {
		TicketOutboundVO vo = new TicketOutboundVO();
		TicketOutbound outbound = getById(id);
		if(Objects.isNull(outbound)){
			throw new ServiceException("单据不存在！");
		}
		List<SysUser> sysUsers = userMapper.selectUserListNoAuth(new SysUser());
		Map<Long, SysUser> sysUserMap=sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
		BeanUtil.copyProperties(outbound,vo);
		vo.setDetails(getDetails(id));
		vo.setFounderName(sysUserMap.get(outbound.getFounder()).getNickName());
		vo.setReviserName(Objects.isNull(outbound.getReviser())?null:sysUserMap.get(outbound.getReviser()).getNickName());
		return vo;
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean delete(Long id) {
		////删除无需校验
		List<TicketProductDetailsDTO> productDetails = getProductDetails(getDetails(id));
		productDetails.forEach(item->{
			item.setBusinessType("DELETE");
			item.setQuantity(item.getQuantity().negate());
		});
		
		boolean b = removeById(id);
		if(b){
			outboundSubService.remove(new LambdaQueryWrapper<TicketOutboundSub>()
					.eq(TicketOutboundSub::getOutboundId,id));
		}
		//记录数量变化
		decreaseService.changeQuantity(productDetails);
		return false;
	}
	
	@Override
	public void isCanBe(Long id) {
	
	}
	
	
	/**
	 * 明细
	 * @param outboundId
	 * @return
	 */
	private List<TicketOutboundSub> getDetails(Long outboundId){
		LambdaQueryWrapper<TicketOutboundSub> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TicketOutboundSub::getOutboundId, outboundId);
		return outboundSubService.list(queryWrapper);
	}
	
	
	/**
	 * 将修改明细转化为产品实体
	 * @param details
	 * @return
	 */
	private List<TicketProductDetailsDTO> getProductDetails(List<TicketOutboundSub> details){
		List<TicketProductDetailsDTO> productDetailsDTOList = new ArrayList<>();
		details.forEach(item->{
			//修改不能增加新产品，如果允许增加新的产品信息，此处需取到产品分类
			TicketProductDetailsDTO detailsDTO = new TicketProductDetailsDTO();
			BeanUtil.copyProperties(item,detailsDTO,new String[]{"id"});
			detailsDTO.setBusinessId(item.getOutboundId());
			productDetailsDTOList.add(detailsDTO);
		});
		return productDetailsDTOList;
	}
	
	
	
	
}
